package com.logistics.delivery.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.logistics.container.entity.domian.Container;
import com.logistics.container.service.ContainerService;
import com.logistics.delivery.entity.domain.Delivery;
import com.logistics.delivery.entity.domain.DeliveryAndPick;
import com.logistics.delivery.entity.model.*;
import com.logistics.delivery.mapper.DeliveryMapper;
import com.logistics.dictionary.entity.model.DictionaryRow;
import com.logistics.dictionary.service.DictionaryService;
import com.logistics.erp.service.ErpInvBillService;
import com.logistics.erp.service.ErpOrderService;
import com.logistics.inventory.entity.domain.Inventory;
import com.logistics.inventory.service.InventoryService;
import com.logistics.map.entity.domain.MapComponents;
import com.logistics.map.service.MapComponentsConvertService;
import com.logistics.map.service.MapComponentsService;
import com.logistics.pick.entity.domain.Pick;
import com.logistics.pick.entity.domain.PickDetailInvBill;
import com.logistics.pick.service.PickDetailService;
import com.logistics.pick.service.PickService;
import com.logistics.pick.entity.domain.PickContainer;
import com.logistics.pick.service.PickContainerService;
import com.logistics.sequence.service.SequenceService;
import com.logistics.utils.aspect.annotation.Insert;
import com.logistics.utils.aspect.annotation.Pager;
import com.logistics.utils.bean.ResultPager;
import com.logistics.utils.bean.TabFilter;
import com.logistics.utils.bean.UserBean;
import com.logistics.utils.constants.Constants;
import com.logistics.utils.exception.MessageException;
import com.logistics.utils.tool.DateUtils;
import com.logistics.utils.tool.StringUtils;
import com.logistics.utils.tool.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class DeliveryService extends ServiceImpl<DeliveryMapper, Delivery> {

    @Autowired
    private SequenceService sequenceService;

    @Autowired
    private MapComponentsService mapComponentsService;

    @Autowired
    private DeliveryContainerService deliveryContainerService;

    @Autowired
    private PickContainerService pickContainerService;

    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private PickService pickService;

    @Autowired
    private ErpInvBillService erpInvbillService;

    @Autowired
    private ErpOrderService erpOrderService;

    @Autowired
    private PickDetailService pickDetailService;

    @Autowired
    private DeliveryMapper deliveryMapper;

    @Autowired
    private ContainerService containerService;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private UserUtils userUtils;

    @Autowired
    private MapComponentsConvertService mapComponentsConvertService;

    @Pager
    public ResultPager pager(DeliveryPager param) {
        IPage<Delivery> page = new Page<>(param.getCurrent(), param.getPageSize());
        LambdaQueryWrapper<Delivery> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotNull(param.getCode()), Delivery::getCode, param.getCode());
        IPage<Delivery> result = this.page(page, queryWrapper);
        return new ResultPager<>(result.getRecords().stream()
                .map(DeliveryRow::build).collect(Collectors.toList()), (int) result.getTotal());
    }

    /**
     * 保存配送单
     *
     * @param save
     */
    @Insert
    public String save(DeliverySave save) throws MessageException {
        UserBean userBean = userUtils.getUserInfo();
        if (StringUtils.isNotNull(save.getSiteId())) {
            String location = mapComponentsService.getLocation(save.getSiteId());
            save.setEndStation(location);
        }
        String deliverId = save.getId();
        if (StringUtils.isNull(save.getId())) {
            String rule = "P" + DateUtils.dateToStringFormat(new Date(), DateUtils.YYYYMMDD);
            String code = sequenceService.getCode(rule, 4);
            save.setCode(rule + code);
            save.setStatus(StringUtils.isNotNull(save.getStatus()) ? save.getStatus() : Constants.DELIVERY_STATE_STANDBY);
            save.setCreator(userBean.getUserCode());
            save.setCreateTime(DateUtils.dateToStringFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            save.setUpdater(userBean.getUserCode());
            save.setUpdateTime(DateUtils.dateToStringFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            save.setCreateOrgCode(userBean.getOrganization());
            save.setCreateDepCode(userBean.getDep());
            Delivery delivery = Delivery.build(save);
            this.save(delivery);
            deliverId = delivery.getId().toString();
        } else {
            save.setUpdater(userBean.getUserCode());
            save.setUpdateTime(DateUtils.dateToStringFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            this.update(Delivery.build(save), new LambdaQueryWrapper<Delivery>().eq(Delivery::getId, save.getId()));
        }
        // 保存托盘信息
        if (StringUtils.isNotNull(save.getDeliveryContainer())) {
            save.getDeliveryContainer().setDelivery(deliverId);
            deliveryContainerService.save(save.getDeliveryContainer());
        }
        if(StringUtils.isNotNull(save.getDeliveryContainers()) && !save.getDeliveryContainers().isEmpty()){
            final String delivery = deliverId;
            deliveryContainerService.save(save.getDeliveryContainers().
                    stream().map(e ->  DeliveryContainerSave.build(delivery, save, e.getContainer(), e.getContainerLevel(), e.getIsEmpty())).
                    collect(Collectors.toList()));
        }
        return deliverId;
    }

    /**
     * 保存 多条同时保存
     * @param saves
     * @throws MessageException
     */
    public void save(List<DeliverySave> saves) throws MessageException {
        for (DeliverySave item : saves) {
            save(item);
        }
    }

    /**
     * 根据状态查找配送单
     *
     * @param status
     * @return
     */
    public List<DeliveryRow> listByStatus(String status, String agvType, String zone) {
        return this.list(new LambdaQueryWrapper<Delivery>().eq(Delivery::getStatus, status)
                        .eq(Delivery::getAgvType, agvType)
                        .eq(Delivery::getZone, zone)
                        .orderByAsc(Delivery::getPriority)).
                stream().map(DeliveryRow::build).collect(Collectors.toList());
    }

    /**
     * 更新配送单 & 拣配单状态信息
     *
     * @param save
     */
    public void updateDeliveryByReqCode(DeliverySave save) {
        System.out.println("AGV返回结果" + JSONObject.toJSONString(save));
        if(StringUtils.isNull(save.getAgv())){
            return;
        }
        // 根据请求编号查找配送单信息
        Delivery delivery = this.getOne(new LambdaQueryWrapper<Delivery>().eq(Delivery::getReqCode, save.getReqCode()));
        if (StringUtils.isNotNull(delivery)) {
            List<String> stations = new ArrayList<>();
            String endStation = delivery.getEndStation();
            if(StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_SUCCESS)){
                // 配送成功后把站点解锁
                if(StringUtils.isEquals(Constants.PICK_AREA_JSZX, delivery.getZone())){
                    endStation = mapComponentsConvertService.forkliftStationByLocation(delivery.getEndStation());
                }
                stations.add(endStation);
            }
            if(StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_CANCEL)){ // 任务取消
                // 释放锁定的结束站点
                mapComponentsService.update(MapComponents.build(false),
                        new LambdaQueryWrapper<MapComponents>().in(MapComponents::getLocation, stations));
                return;
            }
            // 判断有没有接力任务 如果有释放接力任务
            Delivery relayDelivery = this.getOne(new LambdaQueryWrapper<Delivery>().eq(Delivery::getParent, delivery.getId()));
            // 上一个任务配送完成 并且有子任务的时候更新子任务状态
            if(StringUtils.isNotNull(relayDelivery) && StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_SUCCESS)){
                // 释放接力任务
                relayDelivery.setStatus(Integer.parseInt(Constants.DELIVERY_STATE_STANDBY));
                this.updateById(relayDelivery);
            }
            // 回写配送单状态
            this.update(Delivery.build(save),
                    new LambdaQueryWrapper<Delivery>().eq(Delivery::getId, delivery.getId()));
            // 查找已拣配的托盘
            List<DeliveryContainerRow> containerRows = deliveryContainerService.listByDeliveryId(
                    StringUtils.isNotNull(delivery.getParent()) ? delivery.getParent() : delivery.getId());
            // 所有拣配完成的托盘
            List<String> containerCodes = containerRows.stream().
                    map(DeliveryContainerRow::getContainer).collect(Collectors.toList());
            // 拣配站点
            stations.addAll(containerRows.stream().map(DeliveryContainerRow::getStation).
                    collect(Collectors.toList()));
            List<Inventory> inventories = null;
            if(!containerCodes.isEmpty()){
                if(StringUtils.isNull(relayDelivery) && StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_SUCCESS)){
                    // 回写拣配单托盘状态
                    pickContainerService.updateStatusByContainers(containerCodes, save.getStatus());
                    // 查找拣配完成的托盘
                    List<PickContainer> containers = pickContainerService.list(new LambdaQueryWrapper<PickContainer>().
                            eq(PickContainer::getPick, delivery.getPick()).
                            eq(PickContainer::getStatus, Constants.PICK_STATE_SUCCESS));
                    // 如果单据没有拣配完成的托盘更新单据状态
                    if(containers.isEmpty() && StringUtils.isNotNull(delivery.getPick())){
                        // 回写拣配单状态
                        pickService.updateStatusByPickId(delivery.getPick().toString(), save.getStatus());
                    }
                }
                // 查找出所有的库存数据根据托盘编号
                inventories = inventoryService.
                        list(new LambdaQueryWrapper<Inventory>().in(Inventory::getContainer, containerCodes));
            }
            // 配送中
            if (StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_IN) && StringUtils.isNotNull(inventories)) {
                inventoryService.updateBatchById(inventories.stream().map(e -> {
                    e.setAgv(delivery.getAgv());
                    e.setStation("");
                    return e;
                }).collect(Collectors.toList()));
            } else if (StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_SUCCESS) &&
                    StringUtils.isNotNull(inventories)) { // 配送完成
                final String station = endStation;
                inventoryService.updateBatchById(inventories.stream().map(e -> {
                    e.setAgv("");
                    e.setStation(station);
                    return e;
                }).collect(Collectors.toList()));
            }
            if(!stations.isEmpty()){
                // 释放拣配站点
                mapComponentsService.update(MapComponents.build(false),
                        new LambdaQueryWrapper<MapComponents>().in(MapComponents::getLocation, stations));
            }
            if(StringUtils.isEquals(save.getStatus(), Constants.DELIVERY_STATE_IN) && !containerCodes.isEmpty()) {
                Pick pick = pickService.getOne(new LambdaQueryWrapper<Pick>().eq(Pick::getId, delivery.getPick().toString()));
//                List<PickDetail> pickDetails = pickDetailService.list(new LambdaQueryWrapper<PickDetail>().eq(PickDetail::getPick, pick.getId())
//                        .in(PickDetail::getContainer, containerCodes));
                List<PickDetailInvBill> pickDetails = pickDetailService.
                        materials(PickDetailInvBill.build(containerCodes, pick.getId().toString()));
                if(!pickDetails.isEmpty()){
                    // 回写ERP配送时间
                    if(StringUtils.isEquals(pickDetails.get(0).getErpInvBillType(), Constants.PICK_TYPE_NOT_CUBE)){
                        pickDetails.forEach(item -> {
                            erpOrderService.updateOrderDetailDeliveryTime(item.getItemSeqNo());
                        });
                    }else if(StringUtils.isEquals(pickDetails.get(0).getErpInvBillType(), Constants.PICK_TYPE_PAINTING)){
                        pickDetails.forEach(item -> {
                            erpOrderService.updateDeliveryTime(item.getErpInvBillCode(), item.getItemCode());
                        });
                    } else{
                        pickDetails.forEach(item ->{
                            erpOrderService.updateDeliveryTime(item.getErpInvBillCode(), item.getItemWorkCode(), item.getItemCode(), String.valueOf(item.getItemOpNo()));
                        });
                    }
                }

            }
        }
    }

    /**
     * 根据id更新请求编码
     *
     * @param reqCode
     * @param deliveryId
     */
    public void updateReqCodeById(Integer reqCode, Integer deliveryId) {
        this.update(Delivery.build(reqCode, Constants.DELIVERY_STATE_LOCK),
                new LambdaQueryWrapper<Delivery>().eq(Delivery::getId, deliveryId));
    }

    /**
     * 自动配送接口
     *
     * @param id
     * @throws MessageException
     */
    @Transactional
    public void createDelivery(String id) throws MessageException {
        Integer pickId = Integer.parseInt(id);
        Pick pick = pickService.getOne(new LambdaQueryWrapper<Pick>()
                .eq(Pick::getId, pickId));
        if(StringUtils.isNull(pick)){
            throw new MessageException("拣配单不存在");
        }
        List<PickDetailInvBill> pickDetailInvBills = pickDetailService.materials(PickDetailInvBill.build(pickId));
        if (pickDetailInvBills.isEmpty()) {
            throw new MessageException("没有流向信息不能配送");
        }
        //领料单优先级
        Integer priority = pickDetailInvBills.stream().filter(e -> StringUtils.isNotNull(e.getPriority()))
                .map(PickDetailInvBill::getPriority).max(Comparator.comparing(x -> x)).orElse(null);
        // 查找拣配单下面所有已完成拣配的托盘
        List<PickContainer> containers = pickContainerService.findByPickId(pickId);
        //查询托盘所有类型
        List<String> containerTypes = containers.stream().map(PickContainer :: getType).distinct().collect(Collectors.toList());
        //<托盘类型,托盘数组>
        Map<String,List<String>> typeContainerMap = containers.stream().collect(Collectors.groupingBy(PickContainer :: getType, Collectors.mapping(PickContainer :: getContainer, Collectors.toList())));
        // 根据拣配的站点查找所在的区域
        List<String> stations = containers.stream().map(PickContainer::getStation).collect(Collectors.toList());
        // 拣配站点
        List<MapComponents> pickStations = mapComponentsService.list(new LambdaQueryWrapper<MapComponents>().
                in(MapComponents::getLocation, stations));
        // 根据扫描的托盘站点查找区
        List<String> zones = pickStations.stream().map(MapComponents::getZone).distinct().collect(Collectors.toList());
        // 如果扫描的站点区域不一致报错 所以zones只能有一个值
        if(zones.isEmpty()){
            throw new MessageException("没查询到匹配区域，请检查区域码是否正确");
        }
        if(zones.size() >= 2){
            throw new MessageException("区域码不一致请扫描相同区域码");
        }
        // 拣配的区域
        String pickZone = zones.get(0);
        //***********---> start 查找流向区域 <---****************
        // 已经被占用的站点
        List<String> lockStations = inventoryService.list(new LambdaQueryWrapper<Inventory>()
                .isNotNull(Inventory::getStation).ne(Inventory::getStation, "")).stream().map(Inventory::getStation).collect(Collectors.toList());
        /// 查找配送可用站点
        LambdaQueryWrapper<MapComponents> queryWrapper = new LambdaQueryWrapper<MapComponents>().
                eq(MapComponents::getClazz, Constants.COMPONENTS_TYPE_LOCATION).
                eq(MapComponents::getLocationLock, false).notIn(MapComponents::getLocation, lockStations)
                .in(MapComponents::getContainerType, containerTypes)
                .orderByAsc(MapComponents::getLabel);

        List<String> deptCodes = pickDetailInvBills.stream().map(PickDetailInvBill::getDeptCode).distinct().collect(Collectors.toList());
        if(deptCodes.size() > 1){
            throw new MessageException("流向部门不一致");
        }
        List<String> locationAreas = pickDetailInvBills.stream().map(PickDetailInvBill::getLocationArea).distinct().collect(Collectors.toList());
        if(locationAreas.size() > 1){
            throw new MessageException("流向区域不一致");
        }
        List<String> endLocations = pickDetailInvBills.stream().map(PickDetailInvBill::getEndLocation).distinct().collect(Collectors.toList());
        if(endLocations.size() > 1){
            throw new MessageException("流向班组不一致");
        }
        // 装配班组 根据区域走
        if(StringUtils.isEquals(deptCodes.get(0), Constants.WC_CODE_ASSEMBLE)){
            queryWrapper.eq(MapComponents::getLocationArea, locationAreas.get(0));
        }else{ // 其他班组根据结束点走
            queryWrapper.eq(MapComponents::getLocationWcCode, endLocations.get(0));
        }
        // 可用站点
        List<MapComponents> availableLocations = mapComponentsService.list(queryWrapper);
        //<托盘类型,站点数组>
        Map<String,List<String>> typeStaionMap = availableLocations.stream().collect(Collectors.groupingBy(MapComponents :: getContainerType, Collectors.mapping(MapComponents :: getLocation, Collectors.toList())));

        for (Map.Entry<String, List<String>> entry : typeContainerMap.entrySet()) {
            String containerType = entry.getKey();
            List<String> containerCode = entry.getValue();
            List<String> locations = typeStaionMap.get(containerType);
            int locationCount = StringUtils.isNotNull(locations) ? locations.size() : 0;
            if (containerCode.size() > locationCount) {
                throw new MessageException("托盘类型 " + Constants.CONTAINER_TYPE.get(containerType) + " 站点数量不足。");
            }
        }
        //<托盘类型,托盘数组> typeContainerMap
        for (Map.Entry<String, List<String>> entry : typeContainerMap.entrySet()) {
            String containerType = entry.getKey();
            List<String> containerCode = entry.getValue();
            List<String> locations = typeStaionMap.get(containerType);
            for(int i=0; i< containerCode.size(); i++){
                for (PickContainer con :containers){
                    if (StringUtils.isEquals(con.getContainer(), containerCode.get(i))){
                        con.setLocation(locations.get(i));
                    }
                }
            }
        }
        // 判断要配送的站点和拣配站点是否在同一个区域
        List<String> targetZones = availableLocations.stream().map(MapComponents::getZone).distinct().collect(Collectors.toList());
        if(targetZones.isEmpty()){
            throw new MessageException("没找到流向区域，请确认流向是否正确");
        }
        //***********---> end 查找流向区域 <---****************
        //***********---> start 开始创建配送任务 <---****************
        String targetZone = targetZones.get(0);
        // 锁定目的地站点
        List<Integer> lockLocationIds = IntStream.range(0, availableLocations.size()).
                filter(index -> index < containers.size()).mapToObj(index -> availableLocations.get(index).getId()).collect(Collectors.toList());
        if(StringUtils.isEquals(pickZone, targetZone)){
            this.save(IntStream.range(0, containers.size()).mapToObj(index -> DeliverySave.build(Constants.DELIVERY_TYPE_DELIVERY, StringUtils.isNotNull(priority) ? priority.toString() : null,
                    containers.get(index).getStation(), containers.get(index).getLocation(), null, pickId.toString(),
                    Constants.AGV_TYPE_FORKLIFT, containers.get(index).getContainer(), pickZone)).collect(Collectors.toList()));
        } else { // 拣配区域和配送区域不在同一区域需要接力
            List<String> relayLocations = pickStations.stream().map(MapComponents::getRelayWcCode).distinct().collect(Collectors.toList());
            if(relayLocations.size() >= 2){
                throw new MessageException("接力区站点码不一致");
            }
            queryWrapper = new LambdaQueryWrapper<MapComponents>().
                    eq(MapComponents::getClazz, Constants.COMPONENTS_TYPE_LOCATION).
                    eq(MapComponents::getLocationLock, false).notIn(MapComponents::getLocation, lockStations)
                    .orderByAsc(MapComponents::getLabel);
            // 可用接力区站点
            queryWrapper.eq(MapComponents::getLocationWcCode, relayLocations.get(0));
            List<MapComponents> availableRelayLocations = mapComponentsService.list(queryWrapper);
            if(availableRelayLocations.size() < containers.size()){
                throw new MessageException("接力区站点数量不足，请确认");
            }
            String agvType = StringUtils.isEquals(pickZone, Constants.PICK_AREA_LHGF)  ?
                    Constants.AGV_TYPE_FORKLIFT : Constants.AGV_TYPE_BALANCE;

            List<String> availableEndLocations = availableRelayLocations.stream().map(MapComponents::getLocation).collect(Collectors.toList());
            // 查找要配送的点
            Map<String, String> convertEndStationMaps = mapComponentsConvertService.balanceStationByLocation(availableEndLocations);
            List<DeliverySave> saves = IntStream.range(0, containers.size()).mapToObj(index -> DeliverySave.build(Constants.DELIVERY_TYPE_DELIVERY, priority.toString(),
                    containers.get(index).getStation(),
                    StringUtils.isEquals(pickZone, Constants.PICK_AREA_JSZX) ?
                    convertEndStationMaps.get(availableRelayLocations.get(index).getLabel()) : availableRelayLocations.get(index).getLocation(),
                    StringUtils.isEquals(targetZone, Constants.PICK_AREA_JSZX) ?
                            convertEndStationMaps.get(availableRelayLocations.get(index).getLabel()) : availableRelayLocations.get(index).getLocation(),
                    pickId.toString(),
                    agvType, containers.get(index).getContainer(), pickZone)).collect(Collectors.toList());

            int index = 0;
            for (DeliverySave item : saves){
                // 创建接力区任务
                String deliveryId = save(item);
                item.setParent(deliveryId);
                item.setStatus(Constants.DELIVERY_STATE_LOCK);
                item.setStartStation(item.getNextStartStation());
                item.setEndStation(availableLocations.get(index).getLocation());
                item.setDeliveryContainer(null);
                item.setAgvType(StringUtils.isEquals(targetZone, Constants.PICK_AREA_LHGF)  ?
                        Constants.AGV_TYPE_FORKLIFT : Constants.AGV_TYPE_BALANCE);
                item.setZone(targetZone);
                save(item);
                index++;
            }
            // 锁定接力区目的地站点
            lockLocationIds.addAll(IntStream.range(0, availableRelayLocations.size()).
                    filter(i -> i < containers.size()).mapToObj(i -> availableRelayLocations.get(i).getId()).collect(Collectors.toList()));
        }
        // 锁定站点
        mapComponentsService.update(MapComponents.build(true), new LambdaQueryWrapper<MapComponents>().
                in(MapComponents::getId, lockLocationIds));
        //***********---> end 开始创建配送任务 <---****************

    }

    /**
     * 校验该站点是否已经存在托盘
     * @param station
     * @throws MessageException
     */
    public void checkStation(String station) throws MessageException {
        if(deliveryMapper.findUseStation(station) > 0){
            throw new MessageException("该站点正在使用中");
        }
    }

    /**
     * 校验站点是否存在配送任务
     * @param pickId
     * @throws MessageException
     */
    public void checkDelivery(String pickId)throws MessageException{
        Delivery delivery = this.getOne(new LambdaQueryWrapper<Delivery>()
                .eq(Delivery::getPick,pickId)
                .ne(Delivery::getStatus,Constants.DELIVERY_STATE_CANCEL));
        if (StringUtils.isNotNull(delivery))
        {
            throw new MessageException("该站点已存在配送任务，不可再次创建");
        }
    }



    /**
     * 配送单查询
     *
     * @param params
     * @return
     * @throws MessageException
     */
    @Pager
    public ResultPager findDeliveryList(DeliveryAndPickPager params) throws MessageException {
        IPage page = new Page(params.getCurrent() , params.getPageSize());
        params.setCurrent((int) page.offset());
        List<DeliveryAndPick> result =  deliveryMapper.findDeliveryList(params);
        Integer total = deliveryMapper.findDeliveryListTotal(params);

        return new ResultPager(result.stream().map(DeliveryAndPickRow::build).collect(Collectors.toList()),total);
    }

    /**
     * 获取PDA配送单查询画面Tab栏查询条件
     *
     * @return
     * @throws MessageException
     */
    public DeliveryPDARow getFilterList() throws MessageException {
        List<TabFilter> typeFilterlist = this.findTypeFilterlist();
        List<TabFilter> agvFilterlist = this.findAgvFilterlist();
        List<TabFilter> statusFilterlist = this.findStatusFilterlist();
        return DeliveryPDARow.build(typeFilterlist ,agvFilterlist, statusFilterlist);
    }

    /**
     * 获取配送单类型字典项
     *
     * @return
     * @throws MessageException
     */
    public List<TabFilter> findTypeFilterlist() throws MessageException {
        List<DictionaryRow> deliveryTypeList = dictionaryService.getChildrenByCode("delivery_task_type");
        List<TabFilter> filterList = new ArrayList<>();
        filterList.add(TabFilter.unLimitFilter("全部"));
        deliveryTypeList.forEach(e ->
                filterList.add(TabFilter
                        .build(e.getName(), e.getCode(), Constants.TABFILTER_TYPE_CHECKBOX, e.getCode())));
        return filterList;
    }

    /**
     * 获取AGV列表
     *
     * @return
     * @throws MessageException
     */
    public List<TabFilter> findAgvFilterlist() throws MessageException {
        List<MapComponents> agvList = mapComponentsService.list(new LambdaQueryWrapper<MapComponents>().
                eq(MapComponents::getClazz, Constants.COMPONENTS_TYPE_CAR).orderByAsc(MapComponents::getDeviceId));
        List<TabFilter> filterList = new ArrayList<>();
        filterList.add(TabFilter.unLimitFilter("全部"));
        agvList.forEach(e ->
                filterList.add(TabFilter
                        .build(e.getDeviceId(), e.getDeviceId(), Constants.TABFILTER_TYPE_CHECKBOX, e.getDeviceId())));
        return filterList;
    }

    /**
     * 获取PDA单据查询状态字典项
     *
     * @return
     * @throws MessageException
     */
    public List<TabFilter> findStatusFilterlist() throws MessageException {
        List<DictionaryRow> deliveryTypeList = dictionaryService.getChildrenByCode("delivery_status");
        List<TabFilter> filterList = new ArrayList<>();
        filterList.add(TabFilter.unLimitFilter("全部"));
        deliveryTypeList.forEach(e ->
                filterList.add(TabFilter
                        .build(e.getName(), e.getCode(), Constants.TABFILTER_TYPE_CHECKBOX, e.getCode())));
        return filterList;
    }


}
